local CT_SINGLE = 1                 --单牌类型
local CT_DOUBLE = 2                 --对子类型
local CT_SHUN_ZI = 3                --顺子类型
local CT_JIN_HUA = 4                --金花类型
local CT_SHUN_JIN = 5               --顺金类型
local CT_BAO_ZI = 6                 --豹子类型
local CT_SPECIAL = 7                --特殊类型

local MAX_CARD_COUNT = 3

local table_insert = table.insert
local math_floor = math.floor
local M = {}


local function make_card_id(sign,number)
    return sign * 100 + number
end
M.make_card_id = make_card_id

local function extract_card_number(card_id)
    return card_id % 100
end
M.extract_card_number = extract_card_number

local function get_card_color(card_id)
    return math_floor(card_id / 100)
end
M.get_card_color = get_card_color

local function get_card_logic_value(card_id)
    local card_value = extract_card_number(card_id)
    if card_value == 1 then
        return card_value + 13
    end
    return card_value
end
M.get_card_logic_value = get_card_logic_value

local function sort_card_list(tile_list)
    local logic_tile_list = {}
    for i = 1, MAX_CARD_COUNT, 1 do
        table_insert(logic_tile_list, get_card_logic_value(tile_list[i]))
    end

    --排序操作
    local sorted = false
    local tmp_data = nil
    local last = MAX_CARD_COUNT - 1
    repeat
        sorted = true
        for i = 1, last, 1 do
            if logic_tile_list[i] < logic_tile_list[i+1] or (logic_tile_list[i] == logic_tile_list[i+1] and (tile_list[i] < tile_list[i+1])) then
                tmp_data = tile_list[i]
                tile_list[i] = tile_list[i+1]
                tile_list[i+1] = tmp_data
                tmp_data = logic_tile_list[i]
                logic_tile_list[i] = logic_tile_list[i+1]
                logic_tile_list[i+1] = tmp_data
                sorted = false
            end
        end
        last = last - 1
    until(sorted)
end

local function get_card_type(tile_list)
    sort_card_list(tile_list)
    local same_color = true
    local line_card = true

    local first_card_color = get_card_color(tile_list[1])
    local first_card_value = get_card_logic_value(tile_list[1])
    for i=2, #tile_list, 1 do
        if get_card_color(tile_list[i]) ~= first_card_color then
            same_color = false
        end
        if get_card_logic_value(tile_list[i]) + i - 1 ~= first_card_value then
            line_card = false
        end

        --判断结束
        if not same_color and not line_card then
            goto CONTINUE
        end

        ::CONTINUE::
    end

    --特殊A32
    if not line_card then
        local one = false
        local two = false
        local three = false
        for i = 1, MAX_CARD_COUNT, 1 do
            if extract_card_number(tile_list[i]) == 1 then
                one = true
            elseif extract_card_number(tile_list[i]) == 2 then
                two = true
            elseif extract_card_number(tile_list[i]) == 3 then
                three = true
            end
        end
        if one and two and three then
            line_card = true
        end
    end

    --顺金类型
    if same_color and line_card then
        return CT_SHUN_JIN
    end

    --顺子类型
    if not same_color and line_card then
        return CT_SHUN_ZI
    end

    --金花类型
    if same_color and not line_card then
        return CT_JIN_HUA
    end

    --对牌分析
    local double = false
    local panther = true
    for i = 1, MAX_CARD_COUNT, 1 do
        for j = i+1, MAX_CARD_COUNT, 1 do
            if get_card_logic_value(tile_list[i]) == get_card_logic_value(tile_list[j]) then
                double = true
                break
            end
        end
        
        if double then
            break
        end
    end

    --三条豹子分析
    for i = 2, MAX_CARD_COUNT, 1 do
        if panther and first_card_value ~= get_card_logic_value(tile_list[i]) then
            panther = false
        end
    end

    --对子和豹子判断
    if double then
        if panther then
            return CT_BAO_ZI
        end
        return CT_DOUBLE
    end

    --特殊235
    local two = false
    local three = false
    local five = false
    for i = 1, MAX_CARD_COUNT, 1 do
        if extract_card_number(tile_list[i]) == 2 then
            two = true
        elseif extract_card_number(tile_list[i]) == 3 then
            three = true
        elseif extract_card_number(tile_list[i]) == 5 then
            five = true
        end
    end

    if two and three and five then
        return CT_SPECIAL
    end

    return CT_SINGLE
end
M.get_card_type = get_card_type

function M.compare_card(src_type,src_tile_list,dst_type,dst_tile_list)
    --特殊情况分析
    if (dst_type+src_type) == (CT_SPECIAL+CT_BAO_ZI) then
        return src_type > dst_type
    end

    --还原单牌类型
    if dst_type == CT_SPECIAL then
        dst_type = CT_SINGLE
    end
    if src_type == CT_SPECIAL then
        src_type = CT_SINGLE
    end

    if src_type ~= dst_type then
        return src_type > dst_type
    end

    if src_type == CT_BAO_ZI or src_type == CT_SINGLE or src_type == CT_JIN_HUA then --豹子 单牌 金花
        for i = 1, MAX_CARD_COUNT, 1 do
            local dst_value = get_card_logic_value(dst_tile_list[i])
            local src_value = get_card_logic_value(src_tile_list[i])
            if src_value ~= dst_value then
                return src_value > dst_value
            end
        end
        return false
    elseif src_type == CT_SHUN_ZI or src_type == CT_SHUN_JIN then --顺子 顺金 432>A32
        local dst_value = get_card_logic_value(dst_tile_list[1])
        local src_value = get_card_logic_value(src_tile_list[1])  
        --特殊A32
        if dst_value == 14 and get_card_logic_value(dst_tile_list[MAX_CARD_COUNT]) == 2 then
            dst_value = 3
        end
        if src_value == 14 and get_card_logic_value(src_tile_list[MAX_CARD_COUNT]) == 2 then
            src_value = 3
        end

        --对比数值
        if src_value ~= dst_value then
            return src_value > dst_value
        end

        return false
    elseif src_type == CT_DOUBLE then --对子
        local dst_value = get_card_logic_value(dst_tile_list[1])
        local src_value = get_card_logic_value(src_tile_list[1])

        --查找对子/单牌
        local tmp_dst_double = 0
        local tmp_dst_single = 0
        local tmp_src_double = 0
        local tmp_src_single = 0
        if dst_value == get_card_logic_value(dst_tile_list[2]) then
            tmp_dst_double = dst_value
            tmp_dst_single = get_card_logic_value(dst_tile_list[MAX_CARD_COUNT])
        else
            tmp_dst_double = get_card_logic_value(dst_tile_list[MAX_CARD_COUNT])
            tmp_dst_single = dst_value
        end
        if src_value == get_card_logic_value(src_tile_list[2]) then
            tmp_src_double = src_value
            tmp_src_single = get_card_logic_value(src_tile_list[MAX_CARD_COUNT])
        else
            tmp_src_double = get_card_logic_value(src_tile_list[MAX_CARD_COUNT])
            tmp_src_single = src_value
        end
        if tmp_dst_double ~= tmp_src_double then
            return tmp_src_double > tmp_dst_double
        end

        if tmp_dst_single ~= tmp_src_single then
            return tmp_src_single > tmp_dst_single
        end
    end

    return false
end

function M.is_draw(src_tile_list,dst_tile_list)
    local src_type = get_card_type(src_tile_list)
    local dst_type = get_card_type(dst_tile_list)
    if src_type == dst_type then
        for i = 1, MAX_CARD_COUNT, 1 do
            local dst_value = get_card_logic_value(dst_tile_list[i])
            local src_value = get_card_logic_value(src_tile_list[i])
            if dst_value ~= src_value then
                return false
            end
        end
        return true
    end
    return false
end

M.CT_SINGLE = CT_SINGLE
M.CT_DOUBLE = CT_DOUBLE
M.CT_SHUN_ZI = CT_SHUN_ZI
M.CT_JIN_HUA = CT_JIN_HUA
M.CT_SHUN_JIN = CT_SHUN_JIN
M.CT_BAO_ZI = CT_BAO_ZI
M.CT_SPECIAL = CT_SPECIAL

M.MAX_CARD_COUNT = MAX_CARD_COUNT

return M